package com.db4o.odbgen.plugins.java.maingenerator.typedxmlschema;

import java.util.ArrayList;
import java.util.List;

import com.db4o.internal.odbgen.StringUtils;
import com.db4o.odbgen.OdbgenException;
import com.db4o.odbgen.plugins.xmlschema.Element;

/**
 * Represents a field within a class.
 * @author liviug
 *
 */
public class TSField implements XmlElement{
	//IMPORTANT: Whenever adding/removing fields inside this class, be sure to update the copy() method.
	
	private Element _element;
	private List<TSModifier> _modifiers;
	private String _name;
	private DataType _type;
	private String _defaultValue;

	/**
	 * Constructs field given it's components.
	 * @param element The element within XmlSchema.
	 * This may be null if the field is outside XmlSchema. 
	 * @param modifiers The list of modifiers for tha field. This must not be null. It may be an empty list.
	 * @param name The name of the field.
	 * @param type The type of the field.
	 * @throws OdbgenException
	 */
	public TSField(
			Element element, 
			List<TSModifier> modifiers,
			String name, 
			DataType type
			) throws OdbgenException{
		if(modifiers==null){
			throw new OdbgenException("Field modifiers must be specified.");
		}
		if(name==null){
			throw new OdbgenException("Field name must be specified.");
		}
		if(type==null){
			throw new OdbgenException("Field type must be specified.");
		}
		this._element = element;
		this._modifiers = modifiers;
		this._name = name;
		this._type = type;
	}
	
	/**
	 * See {@link XmlElement} for details.
	 */
	@Override
	public Element getElement() {
		return this._element;
	}

	public String getName(){
		return this._name;
	}
	
	public DataType getType(){
		return this._type;
	}
	
	/**
	 * Sets the type of this field.
	 * @param value The new type.
	 */
	public void setType(DataType value){
		this._type = value;
	}

	/**
	 * Sets the default value of this field.
	 * @param defaultValue The content of the default value. This may be anything needed
	 * in order to initalize the field.
	 */
	public void setDefaultValue(String defaultValue) {
		this._defaultValue = defaultValue;
	}
	/**
	 * Gets the default value of this field.
	 */
	public String getValue(){
		return this._defaultValue;
	}
	
	/**
	 * Returns the modifiers of this field.
	 * This may be used to add more modifiers.
	 */
	public List<TSModifier> getModifiers(){
		return this._modifiers;
	}

	/**
	 * Duplicates this field. 
	 * @return The duplicated field.
	 * @throws OdbgenException 
	 */
	public TSField copy() throws OdbgenException {
		List<TSModifier> modifiers = new ArrayList<TSModifier>();
		modifiers.addAll(this.getModifiers());
		TSField res = new TSField(
				this.getElement(),
				modifiers,
				this.getName(),
				this.getType().copy()
				);
		return res;
	}
	
	/**
	 * Returns a string representing this object.
	 * This is used for debug purposes.
	 * @param tabs Number of tabs to indent.
	 */
	String toString(int tabs) {
		StringBuilder res = new StringBuilder();
		
		res.append(String.format("%sfield", StringUtils.tabs(tabs)));
		res.append(StringUtils.newLine());

		res.append(String.format("%sname=%s",
				StringUtils.tabs(tabs+1),
				this.getName()
				));
		res.append(StringUtils.newLine());
		
		res.append(String.format("%stype=%s",
				StringUtils.tabs(tabs+1),
				this.getType().toString()
				));
		res.append(StringUtils.newLine());
		
		return res.toString();
	}

	
	
}
